home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / DrawingInAnAppIcon / FoneController.m < prev    next >
Text File  |  1995-06-12  |  5KB  |  187 lines

  1. //----------------------------------------------------------------------------------------------------
  2. //
  3. //    FoneController
  4. //
  5. //    Inherits From:        Object
  6. //
  7. //    Declared In:        FoneController.h
  8. //
  9. //    Disclaimer
  10. //
  11. //        You may freely copy, distribute and reuse this software and its
  12. //        associated documentation. I disclaim any warranty of any kind, 
  13. //        expressed or implied, as to its fitness for any particular use.
  14. //
  15. //----------------------------------------------------------------------------------------------------
  16. #import "FoneController.h"
  17. #import <dpsclient/dpsNeXT.h>
  18.  
  19.  
  20. #define    _PATTERN_END    13
  21.  
  22. static int    animationPattern[_PATTERN_END] = {0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 0};
  23. static int    patternIterator;
  24. static int    loopCount;
  25.  
  26.  
  27. @implementation FoneController
  28.  
  29. //---------------------------------------------------------------------------------------------------------
  30. //    Private Methods
  31. //---------------------------------------------------------------------------------------------------------
  32. - (NXPoint) _centerPoint: anImage
  33. {
  34.     //  You must center the composited image within the contentView of the
  35.     //  appIcon window.
  36.     
  37.     NXSize    appTileSize;
  38.     NXSize    imageSize;
  39.     NXPoint    centerPoint;
  40.  
  41.     [appTile getSize: &appTileSize];
  42.     [anImage getSize: &imageSize];
  43.     
  44.     if  ( imageSize.width < appTileSize.width ) 
  45.         centerPoint.x += (appTileSize.width - imageSize.width ) / 2.0;
  46.     
  47.     if  ( imageSize.height < appTileSize.height ) 
  48.         centerPoint.y += (appTileSize.height - imageSize.height ) / 2.0;
  49.         
  50.     return centerPoint;
  51. }
  52.  
  53.  
  54. - _display: anImage
  55. {
  56.     //  NXAppTile is composited first at 0,0 of the icon window's content view 
  57.     //  (this is required in order to maintain the NeXT icon look).  'anImage' is 
  58.     //  then composited at center (centering is also a requirement).
  59.  
  60.     NXPoint    contentViewOrigin = { 0.0, 0.0 };
  61.     NXPoint    centerPoint = [self _centerPoint: anImage];
  62.     
  63.     [appIconContentView lockFocus];
  64.     [appTile composite:NX_SOVER toPoint:&contentViewOrigin];
  65.     [anImage composite:NX_SOVER toPoint:¢erPoint];
  66.     [appIconContentView unlockFocus];
  67.     [appIconContentView display];
  68.  
  69.     return self;
  70. }
  71.  
  72.  
  73. - _animate
  74. {
  75.     //  This contains logic for the icon animation (image sequencing).  Three
  76.     //  images are used (contained in imageList).  The animationPattern
  77.     //  provides an index into that list, giving us the right image at the right
  78.     //  time.  The icon will 'ring' twice, and leave the phone off-hook to indicate
  79.     //  unanswered calls.
  80.     
  81.     static int    offset;
  82.     
  83.     [self _display: [imageList objectAt: animationPattern[patternIterator++]]];
  84.     
  85.     if (patternIterator == (_PATTERN_END - offset))
  86.         {
  87.         [self removeTimedEntry];
  88.         patternIterator = 0;
  89.         loopCount++;
  90.         if (loopCount < 2)
  91.             {
  92.             offset = 1;
  93.             [self perform: @selector(ring:) with:self afterDelay:500 cancelPrevious:YES];
  94.             }
  95.         else
  96.             {
  97.             loopCount = offset = 0;
  98.             [self _display: [imageList objectAt: 1]];
  99.             }            
  100.         }
  101.         
  102.     return self;
  103. }
  104.  
  105.  
  106. //---------------------------------------------------------------------------------------------------------
  107. //    DPS Timed Entry Methods
  108. //---------------------------------------------------------------------------------------------------------
  109. void Animate (timedEntry, now, self)
  110.     DPSTimedEntry    timedEntry;
  111.     double            now;
  112.     id                self;
  113. {
  114.     //  This is the callback function for the DPS Timed Entry.  It in turn 
  115.     //  calls our _animate method.  DPS Timed Entries require functions
  116.     //  not methods, as callbacks.
  117.     
  118.     [ (id) self  _animate];
  119. }
  120.  
  121.  
  122. - removeTimedEntry
  123. {
  124.     if (timedEntry)  
  125.         {
  126.         DPSRemoveTimedEntry (timedEntry);
  127.         timedEntry = 0;
  128.         }
  129.         
  130.     return self;
  131. }
  132.  
  133.  
  134. //---------------------------------------------------------------------------------------------------------
  135. //    Application Delegate Method
  136. //---------------------------------------------------------------------------------------------------------
  137. - appDidInit: sender
  138. {
  139.     //  App has inited.  We can now get to the things we need to initialize.
  140.     //  Create the imageList (the list of images used for animation).  Get the 
  141.     //  standard NXAppTile, icon window content view, and move the icon 
  142.     //  somewhere obvious.
  143.     
  144.     imageList = [[List alloc] init];
  145.     [imageList insertObject: [NXImage findImageNamed: "Phone0"] at: 0];
  146.     [imageList insertObject: [NXImage findImageNamed: "Phone1"] at: 1];
  147.     [imageList insertObject: [NXImage findImageNamed: "Phone2"] at: 2];
  148.  
  149.     appTile = [NXImage findImageNamed: "NXAppTile"];
  150.     appIconContentView = [[NXApp appIcon] contentView];
  151.     [[NXApp appIcon] moveTo: 540 :355];
  152.  
  153.     return self;
  154. }
  155.     
  156.     
  157. //---------------------------------------------------------------------------------------------------------
  158. //    Action Methods
  159. //---------------------------------------------------------------------------------------------------------
  160. - ring: sender
  161. {
  162.     //  'Ring' and add a timed entry to begin the animation sequence...
  163.     
  164.     if (timedEntry)  return self;
  165.  
  166.     [[[Sound findSoundFor: "Ring"] play: nil] free];
  167.         timedEntry = DPSAddTimedEntry(0.2, Animate, (void*)self, NX_MODALRESPTHRESHOLD);
  168.  
  169.         return self;
  170. }
  171.  
  172.  
  173. - answer: sender
  174. {
  175.     //  Indicate 'Answer' by placing the fone on-hook.  Do necessary housekeeping.
  176.     
  177.     [self removeTimedEntry];
  178.     [[[Sound findSoundFor: "Ring"] stop: nil] free];
  179.     [self _display: [imageList objectAt: 0]];
  180.     patternIterator = 0;
  181.     loopCount = 0;
  182.     return self;
  183. }
  184.  
  185.  
  186. @end
  187.